package com.dlc.shop.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.dlc.shop.bean.enums.CategoryLevel;
import com.dlc.shop.bean.model.Category;
import com.dlc.shop.bean.model.CategoryLang;
import com.dlc.shop.common.bean.LangConfig;
import com.dlc.shop.common.bean.LangItemConfig;
import com.dlc.shop.common.config.Constant;
import com.dlc.shop.common.exception.YamiShopBindException;
import com.dlc.shop.common.i18n.I18nMessage;
import com.dlc.shop.common.util.PoiExcelUtil;
import com.dlc.shop.manager.impl.LangManager;
import com.dlc.shop.service.CategoryExcelService;
import com.dlc.shop.service.CategoryService;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Sheet;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;


/**
 * @author LGH
 */
@Slf4j
@Service
@AllArgsConstructor
public class CategoryExcelServiceImpl implements CategoryExcelService {

    private static final String PRIMARY_CATEGORY = "一级分类";
    private static final String SECONDARY_CATEGORY = "二级分类";
    private static final String TERTIARY_CATEGORY = "三级分类";
    private final CategoryService categoryService;
    private final LangManager langManager;


    @Override
    public void export(HttpServletResponse response, Long shopId) {
        // 获取导出的分类列表
        List<Category> categories = listCategoryAndLangList(shopId);
        // 存入excel中
        createExcel(categories, response, shopId);
    }


    private List<Category> listCategoryAndLangList(Long shopId) {
        List<Category> categories = categoryService.listCategoryAndLangList(shopId);

        if (CollUtil.isEmpty(categories)) {
            return new ArrayList<>();
        }
        return categories;
    }

    private void createExcel(List<Category> categories, HttpServletResponse response, Long shopId) {
        //通过工具类创建writer
        ExcelWriter writer = ExcelUtil.getBigWriter();
        LangConfig langConfig = langManager.getLangConfig();
        // 商品导出or模板
        List<String> headerList = getHeaderList(shopId, langConfig);
        Sheet sheet = getSheet(writer, langConfig);

        writer.merge(headerList.size() - 1, Objects.equals(I18nMessage.getDbLang(), 0) ? "分类信息" : "Category Information");
        writer.writeRow(headerList);
        try {
            // excel下拉弹窗列表组装
            String[] categoryLevel = {I18nMessage.getMessage("yami.excel.category.primary"),
                    I18nMessage.getMessage("yami.excel.category.secondary"),
                    I18nMessage.getMessage("yami.excel.category.tertiary")};
            PoiExcelUtil.createDropDownList(sheet, categoryLevel, 2, 50000, 3, 3);

            // 分类列表为空
            if (CollUtil.isEmpty(categories)) {
                PoiExcelUtil.writeExcel(response, writer);
                return;
            }

            Map<Long, List<Category>> categoryMap = categories.stream().filter(category -> Objects.nonNull(category.getParentId())).collect(Collectors.groupingBy(Category::getParentId));

            // 一级分类列表不存在
            if (Objects.isNull(categoryMap.get(0L))) {
                PoiExcelUtil.writeExcel(response, writer);
                return;
            }
            int row = 1;
            // 写入分类
            writeCategoryToExcel(categoryMap.get(0L), writer, row, "", categoryMap, shopId, langConfig);

            PoiExcelUtil.writeExcel(response, writer);
        } catch (Exception e) {
            log.error("分类导出:", e);
            throw new YamiShopBindException(e.getMessage());
        }
    }

    private int writeCategoryToExcel(List<Category> categories,ExcelWriter writer, int row, String parentCategoryNames, Map<Long, List<Category>> categoryMap, Long shopId, LangConfig langConfig) {
        if (CollUtil.isEmpty(categories)) {
            return row;
        }
        for (Category category : categories) {
            int col = -1;
            if (CollUtil.isEmpty(category.getCategoryLangList())) {
                continue;
            }
            Map<Integer, String> categoryLangMap = category.getCategoryLangList().stream().filter(categoryLang -> Objects.nonNull(categoryLang.getLang())).collect(Collectors.toMap(CategoryLang::getLang, CategoryLang::getCategoryName));
            // 分类名称
            row++;
            for (LangItemConfig langItemConfig : langConfig.getLangItemList()) {
                PoiExcelUtil.mergeIfNeed(writer, row, row, ++col, col, categoryLangMap.get(langItemConfig.getLang()));
            }

            // 平台端分类独有字段
            if (Objects.equals(shopId, Constant.PLATFORM_SHOP_ID)) {
                String deductionRate = Objects.equals(category.getGrade(), CategoryLevel.THIRD.value()) ? category.getDeductionRate().toString() : "";
                String categoryGrade = PRIMARY_CATEGORY;
                if (Objects.equals(category.getGrade(), CategoryLevel.SECOND.value())) {
                    categoryGrade = SECONDARY_CATEGORY;
                } else if (Objects.equals(category.getGrade(), CategoryLevel.THIRD.value())) {
                    categoryGrade = TERTIARY_CATEGORY;
                }

                PoiExcelUtil.mergeIfNeed(writer, row, row, ++col, col, deductionRate);
                PoiExcelUtil.mergeIfNeed(writer, row, row, ++col, col, categoryGrade);
                PoiExcelUtil.mergeIfNeed(writer, row, row, ++col, col, parentCategoryNames);
            }
            if (categoryMap.containsKey(category.getCategoryId())) {
                // 写入该分类的下级分类
                String parentNames = parentCategoryNames.length() == 0 ?category.getCategoryName():parentCategoryNames + "/" + category.getCategoryName();
                row = writeCategoryToExcel(categoryMap.get(category.getCategoryId()), writer, row, parentNames, categoryMap, shopId, langConfig);
            }
        }
        return row;
    }

    @NotNull
    private List<String> getHeaderList(Long shopId, LangConfig langConfig) {
        List<String> headerList = new ArrayList<>();
        // 分类名称
        for (LangItemConfig langItemConfig : langConfig.getLangItemList()) {
            headerList.add(I18nMessage.getMessage("yami.excel.category.name") + "-" + langItemConfig.getName());
        }
        if (!Objects.equals(shopId, Constant.PLATFORM_SHOP_ID)) {
            return headerList;
        }
        // 分类扣率
        headerList.add(I18nMessage.getMessage("yami.excel.category.deduction.rate"));
        // 分类层级
        headerList.add(I18nMessage.getMessage("yami.excel.category.grade"));
        // 父级分类（格式：一级分类/二级分类，中文名称）
        headerList.add(I18nMessage.getMessage("yami.excel.category.parent"));
        return headerList;
    }

    @NotNull
    private Sheet getSheet(ExcelWriter writer, LangConfig langConfig) {
        Sheet sheet = writer.getSheet();
        int index = -1;
        for (LangItemConfig langItemConfig : langConfig.getLangItemList()) {
            sheet.setColumnWidth(++index, 60 * 256);
        }
        sheet.setColumnWidth(++index, 20 * 256);
        sheet.setColumnWidth(++index, 20 * 256);
        sheet.setColumnWidth(++index, 60 * 256);
        return sheet;
    }

}
